import {reactive} from 'vue';
import {defineStore} from 'pinia';
import {findDictItemList} from '#/api/system/dict-item';

interface DictData {
    key: string | number;
    label: string;
    value: string | number;
    color?: string;
    disabled?: boolean;
}

function fetchDictData<T extends DictData>(key: string, getter: () => T[], format = false) {
    const {requestMap, setDict} = useDictStore();
    const dataList = getter();

    if (dataList.length === 0 && !requestMap.has(key)) {
        requestMap.set(
            key,
            findDictItemList({dict: key})
                .then((res) => {
                    setDict(key, res as T[], format);
                })
                .catch((error) => {
                    requestMap.delete(key);
                })
                .finally(() => {
                    if (dataList.length > 0) {
                        requestMap.delete(key);
                    }
                })
        );
    }
    return dataList;
}

function conver(data: DictData[], format = false): DictData[] {
    return data.map((item) => ({
        key: item.id,
        label: item.label,
        value: format ? Number(item.value) : item.value,
        color: item.color,
        disabled: item.enableStatus === 0,
    }));
}

export const useDictStore = defineStore('core-dict', () => {
    const dictMap = reactive(new Map<string, DictData[]>());
    const requestMap = reactive(new Map<string, Promise<DictData[] | void>>());

    const getDict = (key: string): DictData[] => {
        if (!key) return [];
        if (!dictMap.has(key)) {
            dictMap.set(key, []);
        }
        return dictMap.get(key) || [];
    };

    const setDict = (key: string, data: DictData[], format = false) => {
        if (dictMap.has(key) && dictMap.get(key)?.length === 0) {
            dictMap.get(key)?.push(...conver(data, format));
        } else {
            dictMap.set(key, conver(data, format));
        }
    };

    const getDictData = (key: string, format = false) => {
        return fetchDictData(key, () => getDict(key), format);
    };

    const $reset = () => {
        // dictMap.clear();
        // requestMap.clear();
    }

    return {
        dictMap,
        requestMap,
        getDict,
        setDict,
        getDictData,
        $reset,
    };
});